﻿using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Diagnostics;

namespace ClippingEditor
{
    /// <summary>
    /// 包含下拉列表的输入框
    /// </summary>
    [TemplatePart(Name = "ContentButton", Type = typeof(ToggleButton))]
    public class InputComboBox : TextBox
    {
        #region 静态构造方法，这个不要动

        static InputComboBox()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(InputComboBox), new FrameworkPropertyMetadata(typeof(InputComboBox)));
        }

        #endregion

        #region 操作类型枚举

        public enum OperationType : int
        {
            /// <summary>
            /// 文本内容发生变化
            /// </summary>
            TextChanged = 1,
            /// <summary>
            /// 点击按钮
            /// </summary>
            ButtonClick = 2,
            /// <summary>
            /// 回车键按下
            /// </summary>
            EnterKeyDown = 3
        }
        #endregion

        #region 私有属性
        /// <summary>
        /// 用来表明ResultItem的改变是来自于内部
        /// </summary>
        private bool IsSelfResultItemChanged = false;
        /// <summary>
        /// 用来表明InputText的改变是来自于内部
        /// </summary>
        private bool IsSelfInputTextChanged = false;
        /// <summary>
        /// 弹出窗体是否已经初始化了
        /// </summary>
        private bool IsInitView = false;

        private long changedtime = 0L;
        /// <summary>
        /// 下拉列表数据源发生改变的次数
        /// </summary>
        private long ChangedTime
        {
            get
            {
                changedtime++;
                if (changedtime == long.MaxValue)
                {
                    changedtime = 0L;
                }
                return changedtime;
            }
        }
        /// <summary>
        /// 框内的按钮
        /// </summary>
        private ToggleButton ContentButton;
        /// <summary>
        /// 弹出的下拉框窗口
        /// </summary>
        private Popup window;
        /// <summary>
        /// 装数据的表格
        /// </summary>
        private DataGrid CoreDataGrid;

        /// <summary>
        /// 所属的窗体
        /// </summary>
        private Window OwnerWindow;

        #region 列表内的选中项索引 SelectedIndex

        internal int SelectedIndex
        {
            get { return (int)GetValue(SelectedIndexProperty); }
            set { SetValue(SelectedIndexProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedIndex.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedIndexProperty =
            DependencyProperty.Register("SelectedIndex", typeof(int), typeof(InputComboBox), new UIPropertyMetadata(0));

        #endregion

        #region 列表中的选中项 SelectedItem

        /// <summary>
        /// 列表中的选中项
        /// </summary>
        internal object SelectedItem
        {
            get { return (object)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedItem.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(object), typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion

        #region 私有的表格数据源 SelfDataSource

        public ObservableCollection<object> SelfDataSource
        {
            get { return (ObservableCollection<object>)GetValue(SelfDataSourceProperty); }
            set { SetValue(SelfDataSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelfDataSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelfDataSourceProperty =
            DependencyProperty.Register("SelfDataSource", typeof(ObservableCollection<object>), typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion

        #endregion

        #region 公开属性

        #region 表格的最大高度 MaxListHeight

        /// <summary>
        /// 表格的最大高度
        /// </summary>
        public double MaxListHeight
        {
            get { return (double)GetValue(MaxListHeightProperty); }
            set { SetValue(MaxListHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ListHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MaxListHeightProperty =
            DependencyProperty.Register("MaxListHeight", typeof(double), typeof(InputComboBox), new FrameworkPropertyMetadata(100D));

        #endregion

        #region 表格的最小高度 MinListHeight

        /// <summary>
        /// 表格的最小高度
        /// </summary>
        public double MinListHeight
        {
            get { return (double)GetValue(MinListHeightProperty); }
            set { SetValue(MinListHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ListHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MinListHeightProperty =
            DependencyProperty.Register("MinListHeight", typeof(double), typeof(InputComboBox), new FrameworkPropertyMetadata(40D));

        #endregion

        #region 表格的宽度 ListWidth

        public double ListWidth
        {
            get { return (double)GetValue(ListWidthProperty); }
            set { SetValue(ListWidthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ListWidth.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ListWidthProperty =
            DependencyProperty.Register("ListWidth", typeof(double), typeof(InputComboBox), new FrameworkPropertyMetadata(200D));

        #endregion

        #region 表格的数据源 ItemsSource

        public IEnumerable ItemsSource
        {
            get { return (IEnumerable)GetValue(ItemsSourceProperty); }
            set { SetValue(ItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(IEnumerable), typeof(InputComboBox), new FrameworkPropertyMetadata(null));

        #endregion

        #region 表格的列定义集合 DataGridColumns

        public ObservableCollection<DataGridColumn> DataGridColumns
        {
            get { return (ObservableCollection<DataGridColumn>)GetValue(DataGridColumnsProperty); }
            set { SetValue(DataGridColumnsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DataGridColumns.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataGridColumnsProperty =
            DependencyProperty.Register("DataGridColumns", typeof(ObservableCollection<DataGridColumn>),
            typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion

        #region 分页的长度，每页的条数 PageLength

        public int PageLength
        {
            get { return (int)GetValue(PageLengthProperty); }
            set { SetValue(PageLengthProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PageLength.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PageLengthProperty =
            DependencyProperty.Register("PageLength", typeof(int), typeof(InputComboBox), new UIPropertyMetadata(0));

        #endregion

        #region 按钮是否显示 ButtonVisibility

        public Visibility ButtonVisibility
        {
            get { return (Visibility)GetValue(ButtonVisibilityProperty); }
            set { SetValue(ButtonVisibilityProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ButtonVisibility.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ButtonVisibilityProperty =
            DependencyProperty.Register("ButtonVisibility", typeof(Visibility), typeof(InputComboBox), new UIPropertyMetadata(Visibility.Visible));

        #endregion

        #region 输入框内显示值得路径 ViewPath

        public string ViewPath
        {
            get { return (string)GetValue(ViewPathProperty); }
            set { SetValue(ViewPathProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ViewPath.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ViewPathProperty =
            DependencyProperty.Register("ViewPath", typeof(string), typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion


        #region DataGrid表头高度

        public int ColumnHeaderHeight
        {
            get { return (int)GetValue(ColumnHeaderHeightProperty); }
            set { SetValue(ColumnHeaderHeightProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ColumnHeaderHeight.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ColumnHeaderHeightProperty =
            DependencyProperty.Register("ColumnHeaderHeight", typeof(int), typeof(InputComboBox), new UIPropertyMetadata(int.MinValue));

        #endregion

        #region 弹出框关闭命令
        public ICommand PopupClosedCommand
        {
            get { return (ICommand)GetValue(PopupClosedCommandProperty); }
            set { SetValue(PopupClosedCommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PopupClosedCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PopupClosedCommandProperty =
            DependencyProperty.Register("PopupClosedCommand", typeof(ICommand), typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion

        #region 向外输出的选中结果 ResultItem

        public object ResultItem
        {
            get { return (object)GetValue(ResultItemProperty); }
            set
            {
                if (ResultItem == value && value != null)
                {
                    OnResultItemChanged();
                }
                SetValue(ResultItemProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for ResultItem.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ResultItemProperty =
            DependencyProperty.Register("ResultItem", typeof(object), typeof(InputComboBox),
            new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.AffectsRender,
                (o, e) =>
                {
                    if (o is InputComboBox)
                    {
                        (o as InputComboBox).OnResultItemChanged();
                    }
                }));

        internal void OnResultItemChanged()
        {
            //先去取对应的属性值
            bool isCollapsed = true;
            if (ResultItem != null || IsSelfResultItemChanged == true)
            {
                object o = GetViewValue(ResultItem, ViewPath);
                if (o != null)
                {
                    IsSelfInputTextChanged = true;//内部修改
                    Text = o.ToString();//赋值
                    IsSelfInputTextChanged = false;//内部修改
                }
                isCollapsed = false;
                IsSelfResultItemChanged = false;
            }
            else
            {
                IsSelfInputTextChanged = true;//内部修改
                Text = string.Empty;//赋值
                IsSelfInputTextChanged = false;//内部修改
            }
            if (string.IsNullOrWhiteSpace(Text) == false)
            {
                SelectionStart = Text.Length;//控制光标
            }
            if (window != null && isCollapsed)
                window.IsOpen = false;
        }
        #endregion




        #region 下拉框的样式 DataGridStyle

        public Style DataGridStyle
        {
            get { return (Style)GetValue(DataGridStyleProperty); }
            set { SetValue(DataGridStyleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ListStyle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DataGridStyleProperty =
            DependencyProperty.Register("DataGridStyle", typeof(Style), typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion

        #region 输入框内按钮的样式 ButtonStyle

        public Style ButtonStyle
        {
            get { return (Style)GetValue(ButtonStyleProperty); }
            set { SetValue(ButtonStyleProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ButtonStyle.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ButtonStyleProperty =
            DependencyProperty.Register("ButtonStyle", typeof(Style), typeof(InputComboBox), new UIPropertyMetadata(null));

        #endregion

        #endregion

        #region 私有方法

        #region 构造函数

        public InputComboBox()
        {
            SelfDataSource = new ObservableCollection<object>();
            DataGridColumns = new ObservableCollection<DataGridColumn>();
            DataGridColumns.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(DataGridColumns_CollectionChanged);
            Loaded += new RoutedEventHandler(InputComboBox_Loaded);
            Unloaded += new RoutedEventHandler(InputComboBox_Unloaded);

        }



        #endregion

        #region 输入框样式变化后重新寻找按钮控件

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            if (ContentButton != null)
            {
                ContentButton.Click -= new RoutedEventHandler(Button_Click);
            }
            //设置按钮样式
            ContentButton = Template.FindName("ContentButton", this) as ToggleButton;
            if (ContentButton != null)
            {
                ContentButton.IsChecked = false;
                ContentButton.Click += new RoutedEventHandler(Button_Click);
                ContentButton.Focusable = false;
                ContentButton.DataContext = this;
                ContentButton.SetBinding(ToggleButton.VisibilityProperty, "ButtonVisibility");
                ContentButton.SetBinding(ToggleButton.StyleProperty, "ButtonStyle");
            }
        }



        #endregion

        #region 界面控制

        private void InputComboBox_Loaded(object sender, RoutedEventArgs e)
        {
            //CRootGUI.Common.WPFApplication wa = Application.Current as CRootGUI.Common.WPFApplication;
            //if (wa != null)
            //{
            //    wa.ThemesChanged -= wa_ThemesChanged;
            //    wa.ThemesChanged += wa_ThemesChanged;
            //}
        }

        /// <summary>
        /// Unloade的时候隐藏窗口，保存现在的状态
        /// </summary>
        private void InputComboBox_Unloaded(object sender, RoutedEventArgs e)
        {
            UnloadView();
            //CRootGUI.Common.WPFApplication wa = Application.Current as CRootGUI.Common.WPFApplication;
            //if (wa != null)
            //{
            //    wa.ThemesChanged -= wa_ThemesChanged;
            //}
        }

        private void Owner_StateChanged(object sender, EventArgs e)
        {
            //父窗体状态变化关闭下拉框
            window.IsOpen = false;
        }

        protected override void OnStyleChanged(Style oldStyle, Style newStyle)
        {
            base.OnStyleChanged(oldStyle, newStyle);
            UnloadView();
        }

        /// <summary>
        /// 初始化界面元素
        /// </summary>
        private void InitView()
        {
            //设置弹出窗口
            window = new Popup();
            window.LayoutTransform = Window.GetWindow(this).LayoutTransform;
            CoreDataGrid = new DataGrid();//这个不要动

            window.AllowsTransparency = true;
            window.Child = CoreDataGrid;

            if (ColumnHeaderHeight != int.MinValue)
                CoreDataGrid.ColumnHeaderHeight = ColumnHeaderHeight;

            window.StaysOpen = false;
            window.PlacementTarget = this;
            window.Placement = PlacementMode.Bottom;

            OwnerWindow = System.Windows.Window.GetWindow(this);
            OwnerWindow.StateChanged += new EventHandler(Owner_StateChanged);
            OwnerWindow.MouseDown += new MouseButtonEventHandler(Owner_MouseDown);

            window.PreviewKeyDown += new KeyEventHandler(window_PreviewKeyDown);
            window.LostKeyboardFocus += new KeyboardFocusChangedEventHandler(window_LostKeyboardFocus);
            window.Opened += new EventHandler(window_Opened);
            window.Closed += new EventHandler(window_Closed);

            if (ContentButton != null)
                ContentButton.IsChecked = window.IsOpen;


            //表格设置
            CoreDataGrid.DataContext = this;
            CoreDataGrid.IsReadOnly = true;
            CoreDataGrid.Margin = new Thickness(0);
            //设置为false会导致内存消耗狂增
            //ScrollViewer.SetCanContentScroll(CoreDataGrid, false);
            CoreDataGrid.CanUserAddRows = false;

            CoreDataGrid.CanUserDeleteRows = false;
            CoreDataGrid.CanUserReorderColumns = true;
            CoreDataGrid.CanUserResizeColumns = true;
            CoreDataGrid.CanUserResizeRows = false;
            CoreDataGrid.CanUserSortColumns = true;
            CoreDataGrid.AutoGenerateColumns = false;
            CoreDataGrid.SelectionUnit = DataGridSelectionUnit.FullRow;
            CoreDataGrid.SelectionMode = DataGridSelectionMode.Single;
            CoreDataGrid.HeadersVisibility = DataGridHeadersVisibility.Column;
            CoreDataGrid.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
            CoreDataGrid.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            CoreDataGrid.EnableRowVirtualization = true;
            CoreDataGrid.EnableColumnVirtualization = true;

            CoreDataGrid.SizeChanged += new SizeChangedEventHandler(CoreDataGrid_SizeChanged);

            foreach (var item in DataGridColumns)
            {
                CoreDataGrid.Columns.Add(item);
            }
            CoreDataGrid.SetBinding(DataGrid.ItemsSourceProperty, "SelfDataSource");
            CoreDataGrid.SetBinding(DataGrid.SelectedIndexProperty, "SelectedIndex");
            CoreDataGrid.SetBinding(DataGrid.SelectedItemProperty, "SelectedItem");
            //CoreDataGrid.SetBinding(DataGrid.WidthProperty, "ListWidth");
            CoreDataGrid.SetBinding(DataGrid.MaxHeightProperty, "MaxListHeight");
            CoreDataGrid.SetBinding(DataGrid.MinHeightProperty, "MinListHeight");
            CoreDataGrid.SetBinding(DataGrid.StyleProperty, "DataGridStyle");

            CoreDataGrid.PreviewMouseDoubleClick += new MouseButtonEventHandler(CoreDataGrid_PreviewMouseDoubleClick);

            IsInitView = true;
        }

        void CoreDataGrid_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            window.Width = Math.Max(CoreDataGrid.DesiredSize.Width + 2, this.ActualWidth);
        }

        private void UnloadView()
        {
            if (window != null)
            {
                window.IsOpen = false;
                //解事件
                OwnerWindow.StateChanged -= new EventHandler(Owner_StateChanged);
                OwnerWindow.MouseDown -= new MouseButtonEventHandler(Owner_MouseDown);

                window.PreviewKeyDown -= new KeyEventHandler(window_PreviewKeyDown);
                window.LostKeyboardFocus -= new KeyboardFocusChangedEventHandler(window_LostKeyboardFocus);
                window.Opened -= new EventHandler(window_Opened);
                window.Closed -= new EventHandler(window_Closed);

                window.IsOpen = false;
                window = null;
                OwnerWindow = null;
            }
            if (CoreDataGrid != null)
            {
                BindingOperations.ClearAllBindings(CoreDataGrid);
                CoreDataGrid.PreviewMouseDoubleClick -= new MouseButtonEventHandler(CoreDataGrid_PreviewMouseDoubleClick);
                CoreDataGrid.Columns.Clear();
                CoreDataGrid = null;
            }
            this.IsInitView = false;
        }

        ///// <summary>
        ///// 更换皮肤事件
        ///// </summary>
        //private void wa_ThemesChanged(object sender, Common.ThemeChangedArgs e)
        //{
        //    UnloadView();//卸载窗体
        //}

        private void window_Closed(object sender, EventArgs e)
        {
            if (PopupClosedCommand != null)
                PopupClosedCommand.Execute(null);

            if (ContentButton != null)
                ContentButton.IsChecked = window.IsOpen;
        }

        private void window_Opened(object sender, EventArgs e)
        {
            if (ContentButton != null)
                ContentButton.IsChecked = window.IsOpen;
        }

        #endregion

        #region 各种隐藏列表处理事件

        private void window_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            if (IsKeyboardFocused == false && window != null && !window.IsOpen)
            {
                window.IsOpen = false;
            }
        }

        private void Owner_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (!(e.OriginalSource is InputComboBox) || !((e.OriginalSource as InputComboBox) == this))
            {
                if (window != null)
                    window.IsOpen = false;
            }
        }

        protected override void OnLostKeyboardFocus(KeyboardFocusChangedEventArgs e)
        {
            base.OnLostKeyboardFocus(e);

            if (window != null && !window.IsKeyboardFocusWithin)
            {
                window.IsOpen = false;
                if (LostFocusCommand != null)
                {
                    var m = LostFocusCommand.Invoke(Text);
                    if (m != null && m.Item1)
                    {
                        ResultItem = m.Item2;
                    }
                }
            }
        }

        #endregion

        #region 表格的列发生变化处理

        void DataGridColumns_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (CoreDataGrid == null) return;
            CoreDataGrid.Columns.Clear();
            if (DataGridColumns != null)
            {
                foreach (var item in DataGridColumns)
                {
                    CoreDataGrid.Columns.Add(item);
                }
            }
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 获得对象指定属性的值
        /// </summary>
        /// <param name="o">操作的对象</param>
        /// <param name="path">属性名称</param>
        /// <returns>属性值</returns>
        private object GetViewValue(object o, string path)
        {
            if (o != null && path != null)
            {
                Type type = o.GetType();
                System.Reflection.PropertyInfo pi = type.GetProperty(path);
                if (pi != null)
                {
                    return pi.GetValue(o, null);
                }
                else
                {
                    return null;
                }
            }
            else
            {
                return null;
            }
        }

        #endregion

        #endregion

        #region 核心部分 按键处理 内容变化
        private string preText;
        protected override void OnTextChanged(TextChangedEventArgs e)
        {
            if (Text == preText)
                return;
            preText = Text;
            base.OnTextChanged(e);
            if (IsSelfInputTextChanged == true)
            {
                IsSelfInputTextChanged = false;
                return;
            }
            if (string.IsNullOrWhiteSpace(Text))
            {
                IsSelfResultItemChanged = true;
                ResultItem = null;
                //ClearValue(ResultItemProperty);
                IsSelfResultItemChanged = false;
            }
            OnTextChanged(OperationType.TextChanged);
        }

        /// <summary>
        /// 内容变化处理
        /// </summary>
        private void OnTextChanged(OperationType ot)
        {
            ////设计时不处理
            //if (CRootGUI.Common.Helpers.ViewHelper.IsInDesignMode)
            //    return;
            if (!IsInitView)
                InitView();
            if (ItemsFilterCommand != null)
            {
                if (ItemsFilterCommand(Text, ot))
                {
                    SelfDataSource.Clear();
                    long temptime = this.ChangedTime;

                    if (ItemsSource != null)
                    {
                        foreach (var item in ItemsSource)
                        {
                            if (SelfDataSource.Count < PageLength * 2)
                            {
                                SelfDataSource.Add(item);
                            }
                            else
                            {
                                var temp = new { Time = temptime, Obj = item };
                                this.Dispatcher.BeginInvoke(new Action(() =>
                                {
                                    if (changedtime == temp.Time && window != null && window.IsOpen)
                                    {
                                        SelfDataSource.Add(temp.Obj);
                                    }
                                }), System.Windows.Threading.DispatcherPriority.Background);
                            }
                        }
                    }

                    SelectedIndex = 0;
                    if (SelectedItem != null)
                    {
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                    }
                    
                    window.Width = Math.Max(CoreDataGrid.DesiredSize.Width + 2, this.ActualWidth);
                    window.IsOpen = true;
                    
                }
                else
                {
                    window.IsOpen = false;
                }
            }
        }

        #region 按键事件

        /// <summary>
        /// 点击收缩按钮的处理方式
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            //点击按钮就给输入框设置焦点
            Focus();

            if (!IsInitView)
            {
                InitView();
                OnTextChanged(OperationType.ButtonClick);
                return;
            }

            if (window.IsOpen)
            {
                window.IsOpen = false;
            }
            else
            {
                OnTextChanged(OperationType.ButtonClick);
            }
        }

        /// <summary>
        /// 列表里面双击事件
        /// </summary>
        private void CoreDataGrid_PreviewMouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            DependencyObject dep = e.OriginalSource as DependencyObject;
            while (dep != null && !(dep is DataGridRow))
            {
                dep = VisualTreeHelper.GetParent(dep);
            }
            if (dep != null)
            {
                e.Handled = true;
                OnKeyDown(Key.Enter);
            }
        }

        /// <summary>
        /// 列表窗口里的按键信息
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void window_PreviewKeyDown(object sender, KeyEventArgs e)
        {
            OnKeyDown(e.Key);
            e.Handled = true;
        }

        /// <summary>
        /// 按键处理
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreviewKeyDown(KeyEventArgs e)
        {
            if (e.Handled == false)
            {
                if (e.Key == Key.Up || e.Key == Key.Down || e.Key == Key.PageDown || e.Key == Key.PageUp || e.Key == Key.Enter || e.Key == Key.Escape)
                {
                    OnKeyDown(e.Key);
                    e.Handled = true;
                    return;
                }
            }
            base.OnPreviewKeyDown(e);
        }

        #endregion

        /// <summary>
        /// 核心按键处理，包括向上向下滚动，还有回车键的处理。
        /// </summary>
        private void OnKeyDown(Key key)
        {
            if (!IsInitView)
            {
                InitView();

                //if (key == Key.Enter)
                //{
                //    OnTextChanged(OperationType.EnterKeyDown);
                //    return;
                //}
            }

            if (key == Key.Up)
            {
                if (SelectedIndex >= 1 && SelectedIndex < SelfDataSource.Count)
                {
                    SelectedIndex -= 1;
                    if (SelectedItem != null)
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                }
            }
            else if (key == Key.Down)
            {
                if (SelectedIndex >= 0 && SelectedIndex < SelfDataSource.Count - 1)
                {
                    SelectedIndex += 1;
                    if (SelectedItem != null)
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                }
            }
            else if (key == Key.PageDown && PageLength > 0)
            {
                if (SelectedIndex + PageLength >= 0 && SelectedIndex < SelfDataSource.Count - PageLength)
                {
                    SelectedIndex += PageLength;
                    if (SelectedItem != null)
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                }
                else if (SelectedIndex >= SelfDataSource.Count - PageLength)
                {
                    SelectedIndex = SelfDataSource.Count - 1;
                    if (SelectedItem != null)
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                }
            }
            else if (key == Key.PageUp && PageLength > 0)
            {
                if (SelectedIndex >= PageLength && SelectedIndex - PageLength < SelfDataSource.Count)
                {
                    SelectedIndex -= PageLength;
                    if (SelectedItem != null)
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                }
                else if (SelectedIndex < PageLength)
                {
                    SelectedIndex = 0;
                    if (SelectedItem != null)
                        CoreDataGrid.ScrollIntoView(SelectedItem);
                }
            }
            else if (key == Key.Enter)
            {
                if (!window.IsOpen)
                {
                    //去要一个元素过来，要到了就显示，要不到就算了。
                    if (GetItemCommand != null)
                    {
                        ResultItem = GetItemCommand.Invoke(Text, OperationType.EnterKeyDown);
                    }
                }
                else if (window.IsOpen)
                {
                    IsSelfResultItemChanged = true;
                    ResultItem = SelectedItem;
                    IsSelfResultItemChanged = false;
                    if (window != null)
                        window.IsOpen = false;//确保关闭
                }

                if (OnEnterKeyDownAction != null)
                {
                    OnEnterKeyDownAction.Invoke();
                }
            }
            else if (key == Key.Escape)
            {
                if (window != null)
                    window.IsOpen = false;
            }
        }

        #endregion

        #region 公开方法

        #endregion

        #region 事件处理

        public static readonly DependencyProperty ItemsFilterCommandProperty = DependencyProperty.Register("ItemsFilterCommand", typeof(Func<string, OperationType, bool>), typeof(InputComboBox));
        /// <summary>
        /// 条件过滤命令
        /// </summary>
        public Func<string, OperationType, bool> ItemsFilterCommand
        {
            get
            {
                return (Func<string, OperationType, bool>)GetValue(ItemsFilterCommandProperty);
            }
            set
            {
                SetValue(ItemsFilterCommandProperty, value);
            }
        }

        public static readonly DependencyProperty GetItemCommandProperty = DependencyProperty.Register("GetItemCommand", typeof(Func<string, OperationType, object>), typeof(InputComboBox));
        /// <summary>
        /// 根据条件获得单一元素的方法
        /// </summary>
        public Func<string, OperationType, object> GetItemCommand
        {
            get
            {
                return (Func<string, OperationType, object>)GetValue(GetItemCommandProperty);
            }
            set
            {
                SetValue(GetItemCommandProperty, value);
            }
        }

        public static readonly DependencyProperty LostFocusCommandProperty = DependencyProperty.Register("LostFocusCommand", typeof(Func<string, Tuple<bool, object>>), typeof(InputComboBox));
        /// <summary>
        /// 失去焦点时的处理方法
        /// </summary>
        public Func<string, Tuple<bool, object>> LostFocusCommand
        {
            get
            {
                return (Func<string, Tuple<bool, object>>)GetValue(LostFocusCommandProperty);
            }
            set
            {
                SetValue(LostFocusCommandProperty, value);
            }
        }

        public static readonly DependencyProperty OnEnterKeyDownActionProperty = DependencyProperty.Register("OnEnterKeyDownAction", typeof(Action), typeof(InputComboBox));
        /// <summary>
        /// 按下回车键的事件
        /// </summary>
        public Action OnEnterKeyDownAction
        {
            get
            {
                return (Action)GetValue(OnEnterKeyDownActionProperty);
            }
            set
            {
                SetValue(OnEnterKeyDownActionProperty, value);
            }
        }

        #endregion
    }
}
